package com.tenement.service.impl;

import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.tenement.common.GlobalException;
import com.tenement.entity.Dept;
import com.tenement.entity.Menu;
import com.tenement.enums.RespBusiness;
import com.tenement.mapper.DeptMapper;
import com.tenement.service.DeptService;
import com.tenement.vo.QueryVo;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.tenement.entity.table.DeptTableDef.DEPT;

/**
 *  服务层实现。
 *
 * @author BertXie
 * @since 1.0.1
 */
@Service
@RequiredArgsConstructor
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {

    private final DeptMapper deptMapper;

    @Override
    public List<Dept> treeNode() {
        List<Dept> depts = deptMapper.selectAll();
        return  depts.stream()
                .filter(dept -> dept.getPId() == 0 || depts.stream().noneMatch(other -> other.getId().equals(dept.getPId())))
                .peek(dept -> dept.setChildren(getChildren(dept, depts)))
                .collect(Collectors.toList());
    }

    @Override
    public Page<Dept> list(QueryVo queryVo) {
       QueryWrapper queryWrapper = QueryWrapper.create().from(DEPT)
                .where(DEPT.EMAIL
                        .like(queryVo.getKeyWord(), StrUtil.isNotEmpty(queryVo.getKeyWord()))
                        .or(DEPT.NAME.like(queryVo.getKeyWord(), StrUtil.isNotEmpty(queryVo.getKeyWord())))
                        .or(DEPT.LEADER.like(queryVo.getKeyWord(), StrUtil.isNotEmpty(queryVo.getKeyWord())))
                        .or(DEPT.PHONE.like(queryVo.getKeyWord(), StrUtil.isNotEmpty(queryVo.getKeyWord())))
                )
               .orderBy(DEPT.SORT_ORDER,false)
               .orderBy(DEPT.CREATE_TIME,false);
        Page<Dept> paginate = deptMapper.paginate(queryVo.getPage(), queryVo.getSize(), queryWrapper);
        if (paginate != null && paginate.getTotalRow() > 0) {
            List<Dept> records = paginate.getRecords();
            List<Dept> topLevelMenus = records.stream()
                    .filter(dept -> dept.getPId() == 0 || records.stream().noneMatch(other -> other.getId().equals(dept.getPId())))
                    .peek(dept -> dept.setChildren(getChildren(dept, records)))
                    .collect(Collectors.toList());
            paginate.setRecords(topLevelMenus);
        }
        return paginate;
    }

    private List<Dept> getChildren(Dept dept, List<Dept> menus) {
        return menus.stream()
                .filter(child -> child.getPId().equals(dept.getId()))
                .peek(child -> child.setChildren(getChildren(child, menus)))
                .collect(Collectors.toList());
    }


    @Override
    public int operator(Dept dept) {
        return deptMapper.insertOrUpdateSelective(dept);
    }

    @Override
    public int delete(Long id) {
        long childCount = deptMapper.selectCountByQuery(QueryWrapper.create().from(DEPT).where(DEPT.P_ID.eq(id)));
        if(childCount > 0) {
            throw new GlobalException(RespBusiness.SUBORDINATE_NODE);
        }
        return deptMapper.deleteById(id);
    }


}
